package com.cloudpark.common.util.wechat;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.cloudpark.common.util.ObjectUtil;


public class WxManagerUtil {

    private static final Logger LOG = Logger.getLogger(WxManagerUtil.class);
    
    // 微信授权码
    public static Map<String, String> ACCESS_TOKES = new HashMap<String, String>();

    // token 接口
    private static final String TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";

    // 创建菜单
    private static final String MENU_CREATE = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s";

    // 删除菜单
    private static final String MENU_DELETE = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=%s";

    // 查询菜单

    private static final String MENU_SELECT = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=%s";

    // 发送客服消息
    private static final String CUSTOM_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s";

    // 发送模板消息
    private static final String TEMPLATE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";

    // 网页授权OAuth2.0获取code
    private static final String GET_OAUTH_CODE = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=%s&scope=%s&state=%s#wechat_redirect";

    // 网页授权OAuth2.0获取token
    private static final String GET_OAUTH_TOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";

    // 网页授权OAuth2.0获取用户信息
    private static final String GET_OAUTH_USERINFO = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";

    // 获取WXJSJDK TICKET
    private static final String GET_WEB_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";

    // 微信支付-统一下单接口
    private static final String WXPAY_UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    // 获取关注公众号的用户信息
    private static final String GET_SUBSCRIBE_USERINFO = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN";

    // 获取微信统一下单接口
    public static String getWxPayUnif() {
        return WXPAY_UNIFIEDORDER;
    }

    // 获取token接口
    public static String getTokenUrl(String appId, String appSecret) {
        return String.format(TOKEN, appId, appSecret);
    }

    // 获取菜单创建接口
    public static String getMenuCreateUrl(String token) {
        return String.format(MENU_CREATE, token);
    }

    // 获取菜单删除接口
    public static String getMenuDeleteUrl(String token) {
        return String.format(MENU_DELETE, token);
    }

    // 获取菜单查询接口
    public static String getMenuSelectUrl(String token) {
        return String.format(MENU_SELECT, token);
    }

    // 获取发送客服消息接口
    public static String getCustomMessageUrl(String token) {
        return String.format(CUSTOM_MESSAGE, token);
    }

    // 获取发送模板消息接口
    public static String getTemplateMessageUrl(String token) {
        return String.format(TEMPLATE_MESSAGE, token);
    }

    // 网页授权OAuth2.0获取code
    public static String getOAuthCodeUrl(String appId, String redirectUrl, String scope, String state) {
        return String.format(GET_OAUTH_CODE, appId, urlEncodeUTF8(redirectUrl), "code", scope, state);
    }

    // 网页授权OAuth2.0获取token
    public static String getOAuthTokenUrl(String appId, String appSecret, String code) {
        return String.format(GET_OAUTH_TOKEN, appId, appSecret, code);
    }

    // 网页授权OAuth2.0获取用户信息
    public static String getOAuthUserinfoUrl(String token, String openid) {
        return String.format(GET_OAUTH_USERINFO, token, openid);
    }

    // 获取WXJSJDK TICKET
    public static String getTicketStrUrl(String token) {
        return String.format(GET_WEB_TICKET, token);
    }

    // 获取关注公众号的用户信息
    public static String getUserinfoStrUrl(String token, String openid) {
        return String.format(GET_SUBSCRIBE_USERINFO, token, openid);
    }

    /**
     * 通用接口
     */
    // 获取接口访问凭证
    public static Token getToken(String appId, String appSecret) {
        Token token = null;
        String tockenUrl = WxManagerUtil.getTokenUrl(appId, appSecret);
        JSONObject jsonObject = httpsRequest(tockenUrl, "GET", null);
        if (null != jsonObject && !jsonObject.containsKey("errcode")) {
            try {
                token = new Token();
                token.setAccessToken(jsonObject.getString("access_token"));
                token.setExpiresIn(jsonObject.getIntValue("expires_in"));
            } catch (JSONException e) {
                token = null;// 获取token失败
            }
        } else if (null != jsonObject) {
            token = new Token();
            token.setErrcode(jsonObject.getIntValue("errcode"));
        }
        return token;
    }

    // 发送请求
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        try {
            TrustManager[] tm = { new JEEWeiXinX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);

            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(requestMethod);
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            jsonObject = JSON.parseObject(buffer.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    public static String urlEncodeUTF8(String str) {
        String result = str;
        try {
            result = URLEncoder.encode(str, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    // 获取openId
    public static JSONObject getOpenIdForUrl(String code, String appId, String appSecret) {
        return httpsRequest(WxManagerUtil.getOAuthTokenUrl(appId, appSecret, code), "GET", null);
    }

    // 获取ticket
    public static JSONObject getTicketForUrl(String appId, String appSecret) {
        String token = getToken(appId, appSecret).getAccessToken();
        LOG.info("token========================" + token);
        return httpsRequest(WxManagerUtil.getTicketStrUrl(token), "GET", null);
    }
    
    public static String getTicket(String appId, String appSecret) {
        // TODO Auto-generated method stub
        JSONObject object = WxManagerUtil.getTicketForUrl(appId, appSecret);
        String ticket = null;
        if (null != object) {
            if (object.containsKey("errcode")) {
                ticket = object.getString("ticket");
            } else {
            }
        }
        LOG.info("ticket======================" + ticket);
        return ticket;
    }
    
 // 获取 MsgResponseText 对象
    public static MsgResponseText getMsgResponseText(MsgRequest msgRequest, MsgText msgText) {
        if (msgText != null) {
            MsgResponseText reponseText = new MsgResponseText();
            reponseText.setToUserName(msgRequest.getFromUserName());
            reponseText.setFromUserName(msgRequest.getToUserName());
            reponseText.setMsgType("text");
            reponseText.setCreateTime(new Date().getTime());
            reponseText.setContent(msgText.getContent());
            return reponseText;
        } else {
            return null;
        }
    }

    // 发布菜单
    public static JSONObject publishMenus(String menus, String appId, String appSecret) {
        String token = WxManagerUtil.getToken(appId, appSecret).getAccessToken();
        String url = WxManagerUtil.getMenuCreateUrl(token);
        return WxManagerUtil.httpsRequest(url, "POST", menus);
    }

    // 删除菜单
    public static JSONObject deleteMenus(String appId, String appSecret) {
        String token = WxManagerUtil.getToken(appId, appSecret).getAccessToken();
        String url = WxManagerUtil.getMenuDeleteUrl(token);
        return WxManagerUtil.httpsRequest(url, "GET", null);
    }

    // 查询菜单
    public static JSONObject selectMenus(String appId, String appSecret) {
        String token = WxManagerUtil.getToken(appId, appSecret).getAccessToken();
        String url = WxManagerUtil.getMenuSelectUrl(token);
        return WxManagerUtil.httpsRequest(url, "GET", null);
    }

    // 客服发送消息
    public static JSONObject customMessage(String message, String appId, String appSecret) {
        String token = WxManagerUtil.getToken(appId, appSecret).getAccessToken();
        String url = WxManagerUtil.getCustomMessageUrl(token);
        return WxManagerUtil.httpsRequest(url, "POST", message);
    }

    // 发送模板消息
    public static JSONObject templateMessage(String message, String appId, String appSecret) {
        String token = WxManagerUtil.getToken(appId, appSecret).getAccessToken();
        String url = WxManagerUtil.getTemplateMessageUrl(token);
        return WxManagerUtil.httpsRequest(url, "POST", message);
    }
    
    // 获取用户信息
    public static JSONObject getUserInfo(String appId, String appSecret, String openid) {
        String token = getToken(appId, appSecret).getAccessToken();
        JSONObject object = httpsRequest(getUserinfoStrUrl(token, openid), "GET", null);
        return object;
    }
}

class JEEWeiXinX509TrustManager implements X509TrustManager {
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}
